/*
 * Copyright (C) 2012 POAS.VSTU
 */

package ui;

import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JLabel;

import model.Gamer;
import model.Player;

/**
 * UI-представлние игрока
 */
public class UIPlayer {

    /** Модель игрока */
    private Player mPlayerModel;
    /** UI-колода игрока */
    private UIPlayerCardPile mUICardPile;
    /** Представление имени игрока */
    private JLabel mNameLabel;
    /** Представление количества карт на руках игрока */
    private JLabel mNumCardsLabel;

    /** Левый верхний угол отображения игрока */
    private Point mPosition;
	
	/** Игровая панель. */
	private UIGamePanel mPanel; 

    /** Подсказка решения игрока. */
    private JLabel mDecisionLabel;

    /**
     * Конструктор
     * @param player модель игрока
     * @param gamePanel панель, в которую будет добавлено представление игрока
     */
    UIPlayer(Player player, UIGamePanel gamePanel) {
        mPlayerModel = player;
        mPanel = gamePanel;
        mUICardPile = new UIPlayerCardPile(mPlayerModel.getCards(), this, gamePanel);
        if(player instanceof Gamer) {
            mUICardPile.turnFaceUp();
        } else {
            mUICardPile.turnFaceDown();
        }

        mNameLabel = new JLabel();
        mNameLabel.setText(getName() + " :");
        mNameLabel.setFont(new Font("Candara", Font.BOLD, 20));
        mNameLabel.setForeground(Color.white);
        mNameLabel.setBounds(0, 0, 90, 30);
        mNameLabel.setVisible(true);
        gamePanel.add(mNameLabel);

        mNumCardsLabel = new JLabel();
        mNumCardsLabel.setText("0");
        mNumCardsLabel.setFont(new Font("Candara", Font.BOLD, 20));
        mNumCardsLabel.setForeground(Color.white);
        mNumCardsLabel.setBounds(10, 10, 80, 30);
        mNumCardsLabel.setVisible(true);
        gamePanel.add(mNumCardsLabel);

        mDecisionLabel = new JLabel();
        mDecisionLabel.setFont(new Font("Candara", Font.BOLD, 20));
        mDecisionLabel.setForeground(Color.white);
        mDecisionLabel.setBounds(10, -10, 140, 30);
        mDecisionLabel.setVisible(true);
        gamePanel.add(mDecisionLabel);

        mPlayerModel.setUI(this);
    }



    /** Задать ориентацию стопки */
    public void  setOrientation(Orientation orientation) {
        mUICardPile.setOrientation(orientation);
    }

    /** 
     * Повернуть игрока.
     * @param steps кол-во поворотов в шагах. Один шаг соответствует повороту на
     * 90 градусов. Положительные значения соответствуют повороту по часовой стрелке,
     * отрицательные - против часовой стрелки.
     */
    public void rotate(int steps) {
        Orientation result = getOrientation();
        for(int i = 0; i < steps; i++) {
            if( result == Orientation.NORMAL ) {
                result = Orientation.ROTATED_ANTI_CLOCKWISE;
            } else if( result == Orientation.INVERTED ) {
                result = Orientation.ROTATED_CLOCKWISE;
            } else if( result == Orientation.ROTATED_CLOCKWISE ) {
                result = Orientation.NORMAL;
            } else if( result == Orientation.ROTATED_ANTI_CLOCKWISE ) {
                result = Orientation.INVERTED;
            }
        }
        setOrientation(result);
    }



    /** Задать позицию игрка, его карт и подсказок. */
    public void setLocation(Point p) {
        mPosition = p;


        if (getOrientation() == Orientation.ROTATED_CLOCKWISE
                || getOrientation() == Orientation.ROTATED_ANTI_CLOCKWISE) {

            mNameLabel.setLocation(p.x, p.y - 40);
            mNumCardsLabel.setLocation(p.x + 90, p.y - 40);
            mDecisionLabel.setLocation(p.x,p.y - 10);
        }
        else {
            mNameLabel.setLocation(p.x - 90, p.y);
            mNumCardsLabel.setLocation(p.x - 5, p.y);
            mDecisionLabel.setLocation(p.x - 90, p.y + 30);
        }

        mUICardPile.setLocation(p);
    }

    /** Позиция */
    public Point getLocation() {
        return new Point();
    }

    /** Ориентация игрока */
    public Orientation getOrientation() {
        return mUICardPile.getOrientation();
    }

    /** Получить имя игрока */
    public final String getName() {
        return mPlayerModel.getName();
    }

    /** Границы стопки */
    public Rectangle getBounds() {
        return new Rectangle();
    }

    /** Представление карт игрока. */
    UIPlayerCardPile getUICardPile() {
        return mUICardPile;
    }

    public UICardPile getUIPile() {
        return mUICardPile;
    }

    /** Модель игры. */
    public Player getModel() {
        return mPlayerModel;
    }

    /** Игровая панель. */
    public UIGamePanel getPanel() {
        return mPanel;
    }

    /** Метка с именем игрока. */
    public JLabel getNameLabel() {
        return mNameLabel;
    }

    /** Метка с количеством карт игрока. */
    public JLabel getNumCardsLabel() {
        return mNumCardsLabel;
    }
	
	public void actionUpdateLabels(JComponent previousComponent) {
        actionSetLabels(previousComponent);
    }
    
    private void actionSetLabels(JComponent previousMoved) {
        Action action = new Action(previousMoved, 0);
        action.setLabel(mNumCardsLabel, String.valueOf(mUICardPile.getModel().size()));
        mPanel.addMovement(action);
    }

    /** Подсказка решения игрока. */
    public JLabel getDecisionLabel() {
        return mDecisionLabel;
    }

    /** Показать, что игрок не верит. */
    public void showDisbelieveLabel() {
        mDecisionLabel.setText("Не верит");
        mDecisionLabel.setVisible(true);
        getPanel().paintImmediately(mDecisionLabel.getBounds());
    }

    /** Показать, что игрок верит. */
    public void showBelieveLabel(){
        mDecisionLabel.setText("Верит");
        mDecisionLabel.setVisible(true);
        getPanel().paintImmediately(mDecisionLabel.getBounds());
    }

    /**
     * Мерцание подсказки с именем игрока.
     * Подсказка будет мерцать 2 раза в секунду.
     * Подсказка 3 раза будет мерцать 3 раза, затем вернется к белому цвету.
     */
    public void blinkNameLabel() {
        blinkNameLabel(3);
    }
    /**
     * Мерцание подсказки с именем игрока.
     * Подсказка будет мерцать 2 раза в секунду.
     *
     * @param times сколько раз должна мигнуть подсказка с именем игрока
     */
    public void blinkNameLabel(int times) {
        blinkNameLabel(times, 500);
    }

    /**
     * Мерцание подсказки с именем игрока.
     *
     * @param times сколько раз должна мигнуть подсказка с именем игрока
     * @param pause пауза между мерцаниями
     */
    public void blinkNameLabel(int times, long pause) {
        for (int i = 0; i < times; i++) {
            // Выбрать, каким цветом мерцать на этом шаге цикла
            if (i % 2 == 0) {
                mNameLabel.setForeground(Color.YELLOW);
            }
            else {
                mNameLabel.setForeground(Color.WHITE);
            }
            // Перерисовать метку
            getPanel().paintImmediately(mNameLabel.getBounds());
            // Пауза перед новым шагом цикла
            try {
                Thread.sleep(pause);
            } catch (InterruptedException ex) {
                Logger.getLogger(UIPlayer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        mNameLabel.setForeground(Color.WHITE);
        getPanel().paintImmediately(mNameLabel.getBounds());
    }

    public void highlightName() {
        mNameLabel.setForeground(Color.YELLOW);
        getPanel().paintImmediately(mNameLabel.getBounds());
    }

    public void unhighlightName() {
        mNameLabel.setForeground(Color.WHITE);
        getPanel().paintImmediately(mNameLabel.getBounds());
    }

    /** Действия при начале захода игроком. */
    public void startRound() {
        highlightName();
        mDecisionLabel.setVisible(true);
        mDecisionLabel.setText("Начинает");
        getPanel().paintImmediately(mDecisionLabel.getBounds());
    }

    /** Действия при продолжении захода игроком. */
    public void continueRound() {
        highlightName();
    }

    /**
     * Убрать с экрана признаки активности игрока.
     */
    public void endTurn() {
        unhighlightName();
        mDecisionLabel.setVisible(false);
        getPanel().paintImmediately(mDecisionLabel.getBounds());
        mNumCardsLabel.setText(String.valueOf(getModel().getCards().size()));
        getPanel().paintImmediately(mNumCardsLabel.getBounds());
    }
}
